package main

import (
	"fmt"
	"io/ioutil"
	"os"
	// "reflect"
	"git.oschina.net/kotokz/dlx"
	"strings"
	"time"
)

func main() {

	if len(os.Args) != 2 {
		fmt.Println(`Usage: sudoku <puzzle file>
    where puzzle file contains one or more puzzles in 81 character format.
Each puzzle must be on a separate line and must have 81 characters.
Lines less than 81 characters are ignored.  Any character other than 1-9
(such as 0, space, or .) can be used to represent a blank square.`)
		return
	}

	b, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		fmt.Println(err)
		return
	}

	var solved, failed int
	for _, puzzle := range strings.Split(string(b), "\n") {
		if len(puzzle) < 81 {
			continue
		}
		start := time.Now()

		puzzle = puzzle[:81] // ignore anything else on line
		printGrid("\nPuzzle:", puzzle)
		if s := dlx.Solve(puzzle); s == "" {
			fmt.Println("no solution")
			failed++
		} else {
			printGrid("Solved:", s)

			solved++
		}

		fmt.Println("time spent ", time.Since(start))

		second := time.Now()

		fmt.Println("find all possible solutions")

		printGrid("\nPuzzle:", puzzle)
		if n, solutions := dlx.SolveAll(puzzle); n == 0 {
			fmt.Println("no solution")
			failed++
		} else {
			for i := 0; i < n; i++ {
				solved := fmt.Sprintf("Solution %v", i)
				printGrid(solved, solutions[i])
			}

			solved++
		}

		fmt.Println("time spent ", time.Since(second))
	}
	fmt.Println("\nPuzzles solved:", solved)
	fmt.Println("Failed to solve: ", failed)
}

// print grid (with title) from 81 character string
func printGrid(title, s string) {
	fmt.Println(title)
	for r, i := 0, 0; r < 9; r, i = r+1, i+9 {
		fmt.Printf("%c %c %c | %c %c %c | %c %c %c\n", s[i], s[i+1], s[i+2],
			s[i+3], s[i+4], s[i+5], s[i+6], s[i+7], s[i+8])
		if r == 2 || r == 5 {
			fmt.Println("------+-------+------")
		}
	}
}
